package ICM.client;

import java.awt.Container;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;

import common.*;
import java.awt.Dimension;

public class StatisticInfo extends JPanel implements Observer {
	
	private ClientUI ui;
	private Client c;
	private JTable table;
	private JTable table2;
	private JScrollPane pane;
	private JScrollPane pane2;
	private DefaultTableModel defaultModel = null;
	private DefaultTableModel defaultModel2 = null;
	private JLabel lblDelaysReportFor;
	private JLabel lblDelaysReportFor1;
	private JLabel lblDelaysReportFor2;
	private JLabel lblDelaysReportFor_1;
	private JLabel lblCalculateByInformation;
	private JButton btnCalculate;
	private JComboBox InfoSystemBox;
	private Vector newRow = null;
	private Report PeriodicReport = null;
	private Report[] AllPeriodicReports = null;
	private int[] Performances = null;
	private double[] MedianAndStdDev1 = null;
	private double[] MedianAndStdDev2 = null;
	private FreqDistr[] FreqDistr1 = null;
	private FreqDistr[] FreqDistr2 = null;

	public StatisticInfo(final Client c, final ClientUI ui) {
		this.c = c;
		this.ui = ui;
		c.addObserver(this);
		setLayout(null);
		
		JLabel lblStatisticsInfo = new JLabel("Statistic information");
		lblStatisticsInfo.setFont(new Font("Tahoma", Font.PLAIN, 26));
		lblStatisticsInfo.setBounds(378, 11, 268, 37);
		add(lblStatisticsInfo);
		
		JButton btnBack = new JButton("Back");
		btnBack.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					ui.SetContent(ClientUI.Report_Screen);
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} 
			}
		});
		btnBack.setIcon(new ImageIcon(EmployeesInfo.class.getResource("/client/images/back.png")));
		btnBack.setBounds(818, 452, 114, 37);
		add(btnBack);
		
		JButton btnProducePeriodicReport = new JButton("Produce periodic report");
		btnProducePeriodicReport.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnCalculate.setVisible(false);
				lblDelaysReportFor1.setVisible(false);
				lblDelaysReportFor2.setVisible(false);
				lblDelaysReportFor.setVisible(false);
				lblDelaysReportFor_1.setVisible(false);
				lblCalculateByInformation.setVisible(false);
				InfoSystemBox.setVisible(false);
				CommandMessage msg = new CommandMessage("Get periodic report",null);
				try {
					c.sendToServer(msg);
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				try {
				    Thread.sleep(400);
				} catch(InterruptedException ex) {
				    Thread.currentThread().interrupt();
				}
				int i;
				if (pane!=null)
					remove(pane);
				if (pane2!=null)
					remove(pane2);
				table = new JTable();
				table.setModel(new DefaultTableModel(
					new Object[][] {
					},
					new String[] {
						"Report ID", "Active requests", "Closed requests", "Frozen requests", "Rejected requests", "Working days", "Report date"
					}
				));
				defaultModel = (DefaultTableModel) table.getModel();
				if (PeriodicReport!=null)
				{
					if (defaultModel.getRowCount() > 0) {
					    for (i = defaultModel.getRowCount() - 1; i > -1; i--) {
					    	defaultModel.removeRow(i);
					    }
					}
					newRow = new Vector();
					newRow.add(PeriodicReport.getidReports());
					newRow.add(PeriodicReport.getNumOfActiveRequests());
					newRow.add(PeriodicReport.getNumOfClosedRequests());
					newRow.add(PeriodicReport.getFrozenRequests());
					newRow.add(PeriodicReport.getRejectedRequests());
					newRow.add(PeriodicReport.getSumOfWorkingDays());
					newRow.add(PeriodicReport.getReportDate());
			        defaultModel.addRow(newRow); 
				}
				pane = new JScrollPane(table); 
				pane.setBounds(31, 72, 867, 113);
				add(pane);
			}
		});
		btnProducePeriodicReport.setBounds(75, 342, 182, 37);
		add(btnProducePeriodicReport);
		
		JButton btnAllPeriodicReports = new JButton("All periodic reports");
		btnAllPeriodicReports.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				btnCalculate.setVisible(false);
				lblDelaysReportFor1.setVisible(false);
				lblDelaysReportFor2.setVisible(false);
				lblDelaysReportFor.setVisible(false);
				lblDelaysReportFor_1.setVisible(false);
				lblCalculateByInformation.setVisible(false);
				InfoSystemBox.setVisible(false);
				CommandMessage msg = new CommandMessage("Get all periodic reports",null);
				try {
					c.sendToServer(msg);
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				try {
				    Thread.sleep(400);
				} catch(InterruptedException ex) {
				    Thread.currentThread().interrupt();
				}
				int i;
				if (pane!=null)
					remove(pane);
				if (pane2!=null)
					remove(pane2);
				table = new JTable();
				table.setModel(new DefaultTableModel(
					new Object[][] {
					},
					new String[] {
						"Report ID", "Active requests", "Closed requests", "Frozen requests", "Rejected requests", "Working days", "Report date"
					}
				));
				defaultModel = (DefaultTableModel) table.getModel();
				if (AllPeriodicReports!=null)
				{
					if (defaultModel.getRowCount() > 0) {
					    for (i = defaultModel.getRowCount() - 1; i > -1; i--) {
					    	defaultModel.removeRow(i);
					    }
					}
					for (i=0; i<AllPeriodicReports.length; i++)
					{
						newRow = new Vector();
						newRow.add(AllPeriodicReports[i].getidReports());
						newRow.add(AllPeriodicReports[i].getNumOfActiveRequests());
						newRow.add(AllPeriodicReports[i].getNumOfClosedRequests());
						newRow.add(AllPeriodicReports[i].getFrozenRequests());
						newRow.add(AllPeriodicReports[i].getRejectedRequests());
						newRow.add(AllPeriodicReports[i].getSumOfWorkingDays());
						newRow.add(AllPeriodicReports[i].getReportDate());
				        defaultModel.addRow(newRow); 
					}
				}
				pane = new JScrollPane(table); 
				pane.setBounds(31, 72, 867, 113);
				add(pane);
			}
		});
		btnAllPeriodicReports.setBounds(278, 342, 182, 37);
		add(btnAllPeriodicReports);
		
		JButton btnPerformances = new JButton("Performances");
		btnPerformances.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				btnCalculate.setVisible(false);
				lblDelaysReportFor1.setVisible(false);
				lblDelaysReportFor2.setVisible(false);
				lblDelaysReportFor.setVisible(false);
				lblDelaysReportFor_1.setVisible(false);
				lblCalculateByInformation.setVisible(false);
				InfoSystemBox.setVisible(false);
				CommandMessage msg = new CommandMessage("Get performances",null);
				try {
					c.sendToServer(msg);
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				try {
				    Thread.sleep(400);
				} catch(InterruptedException ex) {
				    Thread.currentThread().interrupt();
				}
				int i;
				if (pane!=null)
					remove(pane);
				if (pane2!=null)
					remove(pane2);
				table = new JTable();
				table.setModel(new DefaultTableModel(
					new Object[][] {
					},
					new String[] {
						"Overall prolongations duration", "Overall added duration"
					}
				));
				defaultModel = (DefaultTableModel) table.getModel();
				if (Performances!=null)
				{
					if (defaultModel.getRowCount() > 0) {
					    for (i = defaultModel.getRowCount() - 1; i > -1; i--) {
					    	defaultModel.removeRow(i);
					    }
					}
					newRow = new Vector();
					newRow.add(Performances[0]);
					newRow.add(Performances[1]);
			        defaultModel.addRow(newRow); 
				}
				pane = new JScrollPane(table); 
				pane.setBounds(31, 72, 867, 113);
				add(pane);
			}
		});
		btnPerformances.setBounds(483, 342, 182, 37);
		add(btnPerformances);
		
		JButton btnDelaysDurationReport = new JButton("Delays durations report");
		btnDelaysDurationReport.setMaximumSize(new Dimension(149, 23));
		btnDelaysDurationReport.setPreferredSize(new Dimension(149, 23));
		btnDelaysDurationReport.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				CommandMessage msg = new CommandMessage("Get median and standard deviation for delays durations",null);
				try {
					c.sendToServer(msg);
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				try {
				    Thread.sleep(400);
				} catch(InterruptedException ex) {
				    Thread.currentThread().interrupt();
				}
								
				CommandMessage msg1 = new CommandMessage("Get frequency distribution for delays durations",null);
				try {
					c.sendToServer(msg1);
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				try {
				    Thread.sleep(400);
				} catch(InterruptedException ex) {
				    Thread.currentThread().interrupt();
				}
				
				CalculateReport1();
			}
		});
		btnDelaysDurationReport.setBounds(158, 452, 208, 37);
		add(btnDelaysDurationReport);
		
		lblDelaysReportFor = new JLabel("Median and standard deviation for delays durations:");
		lblDelaysReportFor.setVisible(false);
		lblDelaysReportFor.setBounds(31, 61, 296, 14);
		add(lblDelaysReportFor);
		
		lblDelaysReportFor_1 = new JLabel("Frequency distribution for delays durations:");
		lblDelaysReportFor_1.setVisible(false);
		lblDelaysReportFor_1.setBounds(500, 59, 296, 14);
		add(lblDelaysReportFor_1);
		
		lblDelaysReportFor1 = new JLabel("Median and standard deviation for number of delays:");
		lblDelaysReportFor1.setVisible(false);
		lblDelaysReportFor1.setBounds(31, 61, 296, 14);
		add(lblDelaysReportFor1);
		
		lblDelaysReportFor2 = new JLabel("Frequency distribution for number of delays:");
		lblDelaysReportFor2.setVisible(false);
		lblDelaysReportFor2.setBounds(500, 59, 296, 14);
		add(lblDelaysReportFor2);
		
		JButton btnNumberOfDelays = new JButton("Number of delays report");
		btnNumberOfDelays.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				CommandMessage msg = new CommandMessage("Get median and standard deviation for number of delays",null);
				try {
					c.sendToServer(msg);
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				try {
				    Thread.sleep(400);
				} catch(InterruptedException ex) {
				    Thread.currentThread().interrupt();
				}								
				CommandMessage msg1 = new CommandMessage("Get frequency distribution for number of delays",null);
				try {
					c.sendToServer(msg1);
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				try {
				    Thread.sleep(400);
				} catch(InterruptedException ex) {
				    Thread.currentThread().interrupt();
				}
				
				CalculateReport2();
			}
		});
		btnNumberOfDelays.setBounds(398, 452, 215, 37);
		add(btnNumberOfDelays);
		
		lblCalculateByInformation = new JLabel("Calculate report by information system:");
		lblCalculateByInformation.setVisible(false);
		lblCalculateByInformation.setBounds(53, 254, 241, 14);
		add(lblCalculateByInformation);
		
		InfoSystemBox = new JComboBox();
		InfoSystemBox.setVisible(false);
		InfoSystemBox.setModel(new DefaultComboBoxModel(new String[] {"","Information System", "Moodle", "Library System", "Computer class", "College Website"}));
		InfoSystemBox.setBounds(51, 279, 191, 20);
		add(InfoSystemBox);
		
		btnCalculate = new JButton("Calculate");
		btnCalculate.setVisible(false);
		btnCalculate.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				String InfoSystem = InfoSystemBox.getSelectedItem().toString();
				if (InfoSystem!="")
				{
					CommandMessage msg = null;
					if (lblDelaysReportFor.isVisible())
						msg = new CommandMessage("Get median and standard deviation for delays durations",new String[] {InfoSystem});
					else
						msg = new CommandMessage("Get median and standard deviation for number of delays",new String[] {InfoSystem});
					try {
						c.sendToServer(msg);
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					try {
					    Thread.sleep(400);
					} catch(InterruptedException ex) {
					    Thread.currentThread().interrupt();
					}
					
					CommandMessage msg2 = null;
					if (lblDelaysReportFor.isVisible())
						msg2 = new CommandMessage("Get frequency distribution for delays durations",new String[] {InfoSystem});
					else
						msg2 = new CommandMessage("Get frequency distribution for number of delays",new String[] {InfoSystem});
					try {
						c.sendToServer(msg2);
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					try {
					    Thread.sleep(400);
					} catch(InterruptedException ex) {
					    Thread.currentThread().interrupt();
					}
					
					if (lblDelaysReportFor.isVisible())
						CalculateReport1();
					else
						CalculateReport2();
				}
			}
		});
		btnCalculate.setBounds(278, 270, 102, 31);
		add(btnCalculate);
	}

	protected void CalculateReport1() {
		btnCalculate.setVisible(true);
		lblDelaysReportFor1.setVisible(false);
		lblDelaysReportFor2.setVisible(false);
		int i;
		if (pane!=null)
			remove(pane);
		table = new JTable();
		table.setModel(new DefaultTableModel(
			new Object[][] {
			},
			new String[] {
				"Median", "Standard deviation"
			}
		));
		defaultModel = (DefaultTableModel) table.getModel();
		if (MedianAndStdDev1!=null && MedianAndStdDev1[0]!=0)
		{
			if (defaultModel.getRowCount() > 0) {
			    for (i = defaultModel.getRowCount() - 1; i > -1; i--) {
			    	defaultModel.removeRow(i);
			    }
			}
			newRow = new Vector();
			newRow.add(MedianAndStdDev1[0]);
			newRow.add(MedianAndStdDev1[1]);
	        defaultModel.addRow(newRow); 
		}
		pane = new JScrollPane(table); 
		pane.setBounds(31, 86, 400, 113);
		add(pane);
		
		if (pane2!=null)
			remove(pane2);
		table2 = new JTable();
		table2.setModel(new DefaultTableModel(
			new Object[][] {
			},
			new String[] {
				"Exception days", "Frequency"
			}
		));
		defaultModel2 = (DefaultTableModel) table2.getModel();
		if (FreqDistr1!=null && FreqDistr1.length>0)
		{
			if (defaultModel2.getRowCount() > 0) {
			    for (i = defaultModel2.getRowCount() - 1; i > -1; i--) {
			    	defaultModel2.removeRow(i);
			    }
			}
	        for (i=0; i<FreqDistr1.length; i++)
			{
				newRow = new Vector();
				newRow.add(FreqDistr1[i].getOverallExceptionDays());
				newRow.add(FreqDistr1[i].getFrequency());
		        defaultModel2.addRow(newRow); 
			}
		}
		pane2 = new JScrollPane(table2); 
		pane2.setBounds(500, 86, 400, 113);
		add(pane2);
		
		lblDelaysReportFor.setVisible(true);
		lblDelaysReportFor_1.setVisible(true);
		lblCalculateByInformation.setVisible(true);
		InfoSystemBox.setVisible(true);
	}
	
	protected void CalculateReport2() {
		btnCalculate.setVisible(true);
		lblDelaysReportFor.setVisible(false);
		lblDelaysReportFor_1.setVisible(false);
		int i;
		if (pane!=null)
			remove(pane);
		table = new JTable();
		table.setModel(new DefaultTableModel(
			new Object[][] {
			},
			new String[] {
				"Median", "Standard deviation"
			}
		));
		defaultModel = (DefaultTableModel) table.getModel();
		if (MedianAndStdDev2!=null && MedianAndStdDev2[0]!=0)
		{
			if (defaultModel.getRowCount() > 0) {
			    for (i = defaultModel.getRowCount() - 1; i > -1; i--) {
			    	defaultModel.removeRow(i);
			    }
			}
			newRow = new Vector();
			newRow.add(MedianAndStdDev2[0]);
			newRow.add(MedianAndStdDev2[1]);
	        defaultModel.addRow(newRow); 
		}
		pane = new JScrollPane(table); 
		pane.setBounds(31, 86, 400, 113);
		add(pane);
		if (pane2!=null)
			remove(pane2);
		table2 = new JTable();
		table2.setModel(new DefaultTableModel(
			new Object[][] {
			},
			new String[] {
				"Exception days", "Frequency"
			}
		));
		defaultModel2 = (DefaultTableModel) table2.getModel();
		if (FreqDistr2!=null && FreqDistr2.length>0)
		{
			if (defaultModel2.getRowCount() > 0) {
			    for (i = defaultModel2.getRowCount() - 1; i > -1; i--) {
			    	defaultModel2.removeRow(i);
			    }
			}
	        for (i=0; i<FreqDistr2.length; i++)
			{
				newRow = new Vector();
				newRow.add(FreqDistr2[i].getOverallExceptionDays());
				newRow.add(FreqDistr2[i].getFrequency());
		        defaultModel2.addRow(newRow); 
			}
		}
		pane2 = new JScrollPane(table2); 
		pane2.setBounds(500, 86, 400, 113);
		add(pane2);
		
		lblDelaysReportFor1.setVisible(true);
		lblDelaysReportFor2.setVisible(true);
		lblCalculateByInformation.setVisible(true);
		InfoSystemBox.setVisible(true);
	}
	
	/**
	 * Handle massage from Observable class in our case Client
	 */
	@Override
	public void update(Observable arg0, Object arg) {
		// TODO Auto-generated method stub
		String msg = "";
		String cmd = "";
		if (arg instanceof TextMessage)
			msg = ((TextMessage)arg).ToDebugMessage();
		else if (arg instanceof CommandMessage) {
			CommandMessage ms=(CommandMessage)arg;
			if(ms.getCommand().equals("Periodic report"))
				PeriodicReport = (Report) ms.getParams()[1];
			else if(ms.getCommand().equals("All periodic reports"))
				AllPeriodicReports = (Report[]) ms.getParams()[1];
			else if(ms.getCommand().equals("Performances"))
				Performances = (int[]) ms.getParams()[1];
			else if(ms.getCommand().equals("Median and standard deviation for delays durations"))
				MedianAndStdDev1 = (double[]) ms.getParams()[1];
			else if(ms.getCommand().equals("Frequency distribution for delays durations"))
				FreqDistr1 = (FreqDistr[]) ms.getParams()[1];
			else if(ms.getCommand().equals("Median and standard deviation for number of delays"))
				MedianAndStdDev2 = (double[]) ms.getParams()[1];
			else if(ms.getCommand().equals("Frequency distribution for number of delays"))
				FreqDistr2 = (FreqDistr[]) ms.getParams()[1];
		}
		else
			msg = arg.toString();
	}
}
